class Solution {
public: 
    vector<int> vis; //0未访问 1访问中 2访问完毕
    vector<vector<int>> graph;
    bool flag=true;

    void TopoSort(int u)
    {
        vis[u]=1; //访问中
        for(int v:graph[u])
        {
            if(vis[v]==0){ //未搜索
                TopoSort(v);
                if(!flag) return; //有环，直接退出
            }
            else if(vis[v]==1) //搜索中->有环
            {
                flag=false; return;
            }
        }
        vis[u]=2; //所有节点访问完毕->本节点访问完毕
    }

    bool canFinish(int n, vector<vector<int>>& prerequisites) {
        vis.resize(n, false);
        graph.resize(n);
        for(auto &edge:prerequisites)
        {
            int v=edge[0], u=edge[1];
            graph[u].push_back(v);
        }
        for(int i=0; i<n&&flag; i++)
            if(!vis[i]) TopoSort(i);

        return flag;
    }
};